#include "VoicePlayerWinImp.h"
#include "BDThread.h"
#include "sndfile.h"

VoicePlayerImp::VoicePlayerImp()
	: m_pFile(NULL)
{
	Pa_Initialize();
}

VoicePlayerImp::~VoicePlayerImp()
{
	Pa_Terminate();
}

void VoicePlayerImp::Play(BDString path)
{
	m_pFile = new SoundFile;
	if (m_pFile->Open(path.c_str()) < 0) {
		return;
	}
	Play();
}

void VoicePlayerImp::Play()
{
	if (m_pFile == NULL) {
		return;
	}

	m_OutputParameters.device = Pa_GetDefaultOutputDevice(); /* default output device */
	m_OutputParameters.channelCount = m_pFile->GetChannels();
	m_OutputParameters.sampleFormat = paInt16;
	m_OutputParameters.suggestedLatency = Pa_GetDeviceInfo(m_OutputParameters.device)->defaultLowOutputLatency;
	m_OutputParameters.hostApiSpecificStreamInfo = NULL;

	int err = Pa_OpenStream(&m_Stream, NULL, &m_OutputParameters, m_pFile->GetSampleRate(), 1024, paClipOff, &VoicePlayerImp::PaStreamCallback, m_pFile);
	if (err != paNoError) {
		Pa_Terminate();
		return;
	}

	if (m_Stream)
	{
		Pa_SetStreamFinishedCallback(m_Stream, &VoicePlayerImp::PaStreamFinishedCallback);
		err = Pa_StartStream(m_Stream);
		if (err != paNoError) {
			Pa_Terminate();
			return;
		}
	}
}

int VoicePlayerImp::PaStreamCallback(
	const void *input, void *output,
	unsigned long frameCount,
	const PaStreamCallbackTimeInfo* timeInfo,
	PaStreamCallbackFlags statusFlags,
	void *userData)
{
	SoundFile* sndfile = (SoundFile*)userData;
	short* buffer = (short*)output;
	if (sndfile->Read(buffer, frameCount) == 0) {
		return paComplete;
	}
	return paContinue;
}

void VoicePlayerImp::PaStreamFinishedCallback(void *userData)
{
	SoundFile* sndfile = (SoundFile*)userData;
	if (sndfile == NULL) {
		return;
	}
	sndfile->Close();
}

void VoicePlayerImp::Stop()
{
	int err = Pa_CloseStream(m_Stream);
	if (err != paNoError) {
		Pa_Terminate();
		return;
	}
}

